import random   
import time   
from pynput.keyboard import Controller, Key, Listener   
from threading import Thread
import pygetwindow as gw
import tkinter as tk
from tkinter import ttk
import os
import sys
from ctypes import windll   

font = "Segoe UI"
PAD_Y = 3

class RandomKeyboardSimulator:
    def __init__(self, gui):
        self.keyboard = Controller()
        self.running = False
        self.paused = False
        self.word_count = 0  # 总字数统计
        self.word_count_pre_min = 0  # 每分钟统计
        self.start_time = time.time()  # 开始时间
        self.gui = gui  # 引用GUI界面实例
        self.common_keys = [
            'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm',
            'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z',
            '0', '1', '2', '3', '4', '5', '6', '7', '8', '9'
        ]
    
    def get_random_key(self):
        # 100%概率选择普通键
        return random.choice(self.common_keys)
    
    def get_random_delay(self):
        # 获取从GUI滑动条调节的按键间隔（0.1到1秒）
        delay = self.gui.key_interval.get()
        if self.gui.randomize_check_var.get():
            return random.uniform(0.001, delay)  # 如果勾选了复选框，返回随机值
        return delay  # 否则返回固定值
    
    def get_key_press_duration(self):
        # 获取从GUI滑动条调节的按键持续时间（0.05到0.5秒）
        duration = self.gui.key_duration.get()
        if self.gui.randomize_check_var.get():
            return random.uniform(0.001, duration)  # 如果勾选了复选框，返回随机值
        return duration  # 否则返回固定值
    
    def press_key(self, key):
        try:
            self.keyboard.press(key)
            duration = self.get_key_press_duration()
            # 按键按下持续时间
            print(f"按下键 {key}，持续时间 {duration:.2f} 秒")
            time.sleep(duration)
            self.keyboard.release(key)
            self.word_count += 1
            self.gui.update_word_count(self.word_count)
            self.gui.insert_to_textbox(key)  # 将字符插入文本框

        except Exception as e:
            print(f"按键 {key} 出错: {e}")

    def simulate(self):
        self.running = True
        print("开始随机键盘模拟 (按Esc停止, F1开始, F2暂停)...")
        try:
            while self.running:
                if self.paused:
                    print("模拟已暂停...")
                    time.sleep(1)  # 暂停时每隔1秒检查一次
                    continue
                
                key = self.get_random_key()
                delay = self.get_random_delay()
                
                print(f"等待 {delay:.2f} 秒后按下: {key}")
                time.sleep(delay)
                
                self.press_key(key)
                
                # 每分钟更新一次每分钟字数
                if time.time() - self.start_time >= 60:
                    words_per_minute = self.word_count - self.word_count_pre_min
                    self.gui.update_wpm(words_per_minute)
                    self.word_count_pre_min = self.word_count
                    self.start_time = time.time()  # 重置开始时间
        except KeyboardInterrupt:
            self.stop()
    
    def stop(self):
        self.running = False
        print("\n已停止键盘模拟")

    def on_press(self, key):
        # 启动、暂停、停止控制
        if key == Key.esc:
            print("检测到Esc键，正在停止模拟...")
            self.stop()
            return False  # 停止监听
        elif key == Key.f1:  # F1键用于开始模拟
            if not self.running:
                print("检测到F1键，开始模拟...")
                self.paused = False  # 确保模拟继续
                self.simulate_thread = Thread(target=self.simulate)
                self.simulate_thread.start()
        elif key == Key.f2:  # F2键用于暂停模拟
            if not self.paused:
                print("检测到F2键，暂停模拟...")
                self.paused = True  # 暂停模拟
            else:
                print("模拟已暂停，按F2恢复模拟...")
                self.paused = False  # 恢复模拟


class GUI:
    def __init__(self, root):
        self.root = root

        # style = ttk.Style()
        # style.theme_use('alt')  # 或 'clam', 'alt' 等
        # style.configure('TButton', font=font)
        # print(style.theme_names())

        # 获取当前屏幕的DPI缩放比例   
        dpi = root.winfo_fpixels('1i')  # 获取1英寸的像素数   
        scaling = dpi / 96.0  # 96是标准DPI

        # 设置tkinter缩放因子
        root.tk.call('tk', 'scaling', scaling)
        self.root.title("PUA the Bango Cat V1.2.0 By 一天两根冰棍")
        self.root.geometry("500x500")
        self.root.iconbitmap("icon128.ico")
        
        # 字数统计标签
        self.word_count_label = tk.Label(self.root, text="字数: 0", font=(font, 14))
        self.word_count_label.pack(pady=PAD_Y)
        
        # 每分钟字数显示标签
        self.wpm_label = tk.Label(self.root, text="每分钟字数: 0", font=(font, 14))
        self.wpm_label.pack(pady=PAD_Y)
        
        # 输入区域
        self.textbox = tk.Text(self.root, width=10, height=2, wrap=tk.WORD, font=(font, 12))
        self.textbox.pack(pady=PAD_Y)
        
        # 按钮
        self.start_button = tk.Button(self.root, text="开始 (F1)", width=20, command=self.start_simulation)
        self.start_button.pack(pady=PAD_Y)

        self.pause_button = tk.Button(self.root, text="暂停 (F2)", width=20, command=self.toggle_pause)
        self.pause_button.pack(pady=PAD_Y)

        self.stop_button = tk.Button(self.root, text="停止 (Esc)", width=20, command=self.stop_simulation)
        self.stop_button.pack(pady=PAD_Y)
        
        # 按键间隔设置
        self.interval_label = tk.Label(self.root, text="按键间隔时间 (秒):", font=(font, 12))
        self.interval_label.pack(pady=PAD_Y)
        self.key_interval = tk.Scale(self.root, from_=0.02, to=1.0, orient=tk.HORIZONTAL, resolution=0.01, length=300)
        self.key_interval.set(0.5)  # 默认间隔时间
        self.key_interval.pack(pady=PAD_Y)

        # 按键持续时间设置
        self.duration_label = tk.Label(self.root, text="按键持续时间 (秒):", font=(font, 12))
        self.duration_label.pack(pady=PAD_Y)
        self.key_duration = tk.Scale(self.root, from_=0.02, to=1.0, orient=tk.HORIZONTAL, resolution=0.01, length=300)
        self.key_duration.set(0.2)  # 默认持续时间
        self.key_duration.pack(pady=PAD_Y)
        
        # 随机化设置复选框
        self.randomize_check_var = tk.IntVar()
        self.randomize_check = tk.Checkbutton(self.root, text="使用随机按键间隔和持续时间", variable=self.randomize_check_var)
        self.randomize_check.pack(pady=PAD_Y)
        
        # 初始化模拟器
        self.simulator = RandomKeyboardSimulator(self)
        self.simulator_thread = None
        self.listener = Listener(on_press=self.simulator.on_press)
        self.listener.start()

        # 绑定窗口关闭事件
        self.root.protocol("WM_DELETE_WINDOW", self.stop_simulation)

    def start_simulation(self):
        # 启动模拟
        if not self.simulator.running:
            print("启动模拟...")
            self.simulator.simulate_thread = Thread(target=self.simulator.simulate)
            self.simulator.simulate_thread.start()

    def toggle_pause(self):
        # 切换暂停状态
        if self.simulator.paused:
            print("恢复模拟...")
            self.simulator.paused = False
        else:
            print("暂停模拟...")
            self.simulator.paused = True

    def stop_simulation(self):
        # 停止模拟
        print("停止模拟...")
        self.simulator.stop()
        self.root.quit()  # 退出应用

    def update_word_count(self, count):
        # 更新字数显示
        self.word_count_label.config(text=f"字数: {count}")

    def insert_to_textbox(self, text):
        # 清空文本框并插入字符
        self.textbox.delete("1.0", tk.END)
        self.textbox.insert(tk.END, text)

    def update_wpm(self, wpm):
        # 更新每分钟字数显示
        self.wpm_label.config(text=f"每分钟字数: {int(wpm)}")

# 使用示例   
if __name__ == "__main__":
    windll.shcore.SetProcessDpiAwareness(1)  # 1 = 系统DPI感知，2 = 每显示器DPI感知
    root = tk.Tk()
    gui = GUI(root)
    root.mainloop()
